using System.Collections.Generic;
using ProtoModels;
using UnityEngine;

public static class ProtoModelExtensions
{
	private class ScoreDAOMerger : IMergeInterface<ScoreDAO>
	{
		public bool MyEquals(ScoreDAO score1, ScoreDAO score2)
		{
			return score1.tournamentType == score2.tournamentType;
		}

		public ScoreDAO MyResolver(ScoreDAO score1, ScoreDAO score2)
		{
			ScoreDAO scoreDAO = new ScoreDAO();
			scoreDAO.bronze = GGResolveConflict.ResolveConflictTakeMax(score1.bronze, score2.bronze);
			scoreDAO.silver = GGResolveConflict.ResolveConflictTakeMax(score1.silver, score2.silver);
			scoreDAO.gold = GGResolveConflict.ResolveConflictTakeMax(score1.gold, score2.gold);
			return scoreDAO;
		}
	}

	private class OwnedItemDAOMerger : IMergeInterface<OwnedItemDAO>
	{
		public bool MyEquals(OwnedItemDAO item1, OwnedItemDAO item2)
		{
			return item1.name == item2.name;
		}

		public OwnedItemDAO MyResolver(OwnedItemDAO item1, OwnedItemDAO item2)
		{
			return item1;
		}
	}

	private class CarrerStageDAOMerger : IMergeInterface<CarrerStageDAO>
	{
		public bool MyEquals(CarrerStageDAO carrer1, CarrerStageDAO carrer2)
		{
			return carrer1.name == carrer2.name;
		}

		public CarrerStageDAO MyResolver(CarrerStageDAO carrer1, CarrerStageDAO carrer2)
		{
			CarrerStageDAO carrerStageDAO = new CarrerStageDAO();
			carrerStageDAO.name = carrer1.name;
			carrerStageDAO.bestScore = GGResolveConflict.ResolveConflictTakeMax(carrer1.bestScore, carrer2.bestScore);
			carrerStageDAO.stars = GGResolveConflict.ResolveConflictTakeMax(carrer1.stars, carrer2.stars);
			carrerStageDAO.timesPlayed = GGResolveConflict.ResolveConflictTakeMax(carrer1.timesPlayed, carrer2.timesPlayed);
			return carrerStageDAO;
		}
	}

	private class CareerGroupDAOMerger : IMergeInterface<CareerGroupDAO>
	{
		public bool MyEquals(CareerGroupDAO group1, CareerGroupDAO group2)
		{
			return group1.id == group2.id;
		}

		public CareerGroupDAO MyResolver(CareerGroupDAO group1, CareerGroupDAO group2)
		{
			if (group1.playedGames > group2.playedGames)
			{
				return group1;
			}
			return group2;
		}
	}

	public static PlayerModel DefaultConflictResolution(this PlayerModel localModel, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		PlayerModel model = null;
		if (!ProtoIO.LoadFromByteStream<PlayerModel>(serverBytes, out model))
		{
			return localModel;
		}
		if (model == null)
		{
			return localModel;
		}
		if (localModel == null)
		{
			return model;
		}
		byte[] previousServerBytes = sync.GetPreviousServerBytes(fileKey);
		PlayerModel model2 = null;
		if (!ProtoIO.LoadFromByteStream<PlayerModel>(previousServerBytes, out model2))
		{
			model2 = new PlayerModel();
		}
		PlayerModel playerModel = new PlayerModel();
		playerModel.shownTutorial = localModel.shownTutorial || model.shownTutorial;
		playerModel.playerRatedApp = localModel.playerRatedApp || model.playerRatedApp;
		playerModel.coinCount = model.coinCount;
		playerModel.shownMainMenuTutorial = localModel.shownMainMenuTutorial || model.shownMainMenuTutorial;
		playerModel.score = model.score;
		playerModel.leagueGamesPlayed = model.leagueGamesPlayed;
		playerModel.arcadeGamesPlayed = model.arcadeGamesPlayed;
		playerModel.playerLikedFacebookPage = localModel.playerLikedFacebookPage || model.playerLikedFacebookPage;
		playerModel.starsForCoinsTipShown = localModel.starsForCoinsTipShown || model.starsForCoinsTipShown;
		playerModel.creationTime = model.creationTime;
		playerModel.usedShoe = model.usedShoe;
		playerModel.usedRacket = model.usedRacket;
		playerModel.numBalls = model.numBalls;
		playerModel.lastBallsDelivery = localModel.lastBallsDelivery;
		playerModel.leagueTutorialShown = localModel.leagueTutorialShown || model.leagueTutorialShown;
		playerModel.spinTutorialShown = localModel.spinTutorialShown || model.spinTutorialShown;
		playerModel.multiplayerMatchPlayed = localModel.multiplayerMatchPlayed || model.multiplayerMatchPlayed;
		playerModel.multiplayerWins = model.multiplayerWins;
		playerModel.multiplayerLoses = model.multiplayerLoses;
		playerModel.timeStartedCollectingPoints = model.timeStartedCollectingPoints;
		playerModel.countryPoints = model.countryPoints;
		playerModel.rankingsScore = model.rankingsScore;
		playerModel.competitionStart = model.competitionStart;
		playerModel.competitionEnd = model.competitionEnd;
		playerModel.usedCourt = model.usedCourt;
		playerModel.usedLook = model.usedLook;
		playerModel.usedCameraView = model.usedCameraView;
		playerModel.skills = GGResolveConflict.ResolveConflictTakeRemoteListIfNotEmpty(model.skills, localModel.skills);
		playerModel.skillPoints = model.skillPoints;
		playerModel.trainings = GGResolveConflict.ResolveConflictTakeRemoteListIfNotEmpty(model.trainings, localModel.trainings);
		playerModel.name = model.name;
		playerModel.flag = model.flag;
		playerModel.trainingsCooldown = GGResolveConflict.ResolveConflictTakeRemoteListIfNotEmpty(model.trainingsCooldown, localModel.trainingsCooldown);
		playerModel.trainingsToDisplay = GGResolveConflict.ResolveConflictTakeRemoteListIfNotEmpty(model.trainingsToDisplay, localModel.trainingsToDisplay);
		playerModel.look = GGResolveConflict.ResolveConflictTakeRemoteListIfNotEmpty(model.look, localModel.look);
		playerModel.lookChosen = model.lookChosen || localModel.lookChosen;
		playerModel.lastTimeTookEnergy = model.lastTimeTookEnergy;
		playerModel.energy = model.energy;
		playerModel.energyDrinkCount = model.energyDrinkCount;
		playerModel.energyDrinkGiven = model.energyDrinkGiven;
		playerModel.version = model.version;
		playerModel.purchases = localModel.purchases;
		playerModel.notificationsOff = localModel.notificationsOff;
		playerModel.eloRating = model.eloRating;
		playerModel.idNum = model.idNum;
		playerModel.timeToNextFreeCoins = GGResolveConflict.ResolveConflictTakeMax(model.timeToNextFreeCoins, localModel.timeToNextFreeCoins);
		playerModel.timeToNextDailyCoins = model.timeToNextDailyCoins;
		playerModel.DailyCoinsCount = model.DailyCoinsCount;
		playerModel.multiplayerMessages = GGResolveConflict.ResolveConflictTakeRemoteListIfNotEmpty(model.multiplayerMessages, localModel.multiplayerMessages);
		playerModel.practiceModeGamesPlayed = model.practiceModeGamesPlayed;
		playerModel.x01ModeGamesPlayed = model.x01ModeGamesPlayed;
		playerModel.aroundTheClockGamesPlayed = model.aroundTheClockGamesPlayed;
		playerModel.aiGamesPlayed = model.aiGamesPlayed;
		playerModel.passAndPlayGamesPlayed = model.passAndPlayGamesPlayed;
		playerModel.pid = model.pid;
		playerModel.coins = Mathf.Max(0, model.coins + localModel.coinsSinceLastSync);
		playerModel.coinsSinceLastSync = localModel.coinsSinceLastSync;
		playerModel.giraffeDollars = Mathf.Max(0, model.giraffeDollars + localModel.dollarsSinceLastSync);
		playerModel.dollarsSinceLastSync = localModel.dollarsSinceLastSync;
		playerModel.gamesWon = model.gamesWon + localModel.gamesWonSinceLastSync;
		playerModel.gamesWonSinceLastSync = localModel.gamesWonSinceLastSync;
		return playerModel;
	}

	public static LeagueDAO DefaultConflictResolution(this LeagueDAO localLeague, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		LeagueDAO model = null;
		if (!ProtoIO.LoadFromByteStream<LeagueDAO>(serverBytes, out model))
		{
			return localLeague;
		}
		return model;
	}

	public static TournamentDAO DefaultConflictResolution(this TournamentDAO localTournament, GGCloudSyncFileIOSync sync, string fileKey)
	{
		return null;
	}

	public static TournamentScoreDAO DefaultConflictResolution(this TournamentScoreDAO localTournamentScore, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		TournamentScoreDAO model = null;
		if (!ProtoIO.LoadFromByteStream<TournamentScoreDAO>(serverBytes, out model))
		{
			return localTournamentScore;
		}
		if (model == null || model.participants == null)
		{
			return localTournamentScore;
		}
		if (localTournamentScore == null || localTournamentScore.participants == null)
		{
			return model;
		}
		TournamentScoreDAO tournamentScoreDAO = new TournamentScoreDAO();
		tournamentScoreDAO.participants = GGResolveConflict.ResolveConflictMerge(model.participants, localTournamentScore.participants, new ScoreDAOMerger());
		return tournamentScoreDAO;
	}

	public static OwnedItemsDAO DefaultConflictResolution(this OwnedItemsDAO localOwnedItems, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		OwnedItemsDAO model = null;
		if (!ProtoIO.LoadFromByteStream<OwnedItemsDAO>(serverBytes, out model))
		{
			return localOwnedItems;
		}
		if (model == null || model.ownedItems == null)
		{
			return localOwnedItems;
		}
		if (localOwnedItems == null || localOwnedItems.ownedItems == null)
		{
			return model;
		}
		OwnedItemsDAO ownedItemsDAO = new OwnedItemsDAO();
		ownedItemsDAO.ownedItems = GGResolveConflict.ResolveConflictMerge(model.ownedItems, localOwnedItems.ownedItems, new OwnedItemDAOMerger());
		return ownedItemsDAO;
	}

	public static CarrerDAO DefaultConflictResolution(this CarrerDAO localCarrer, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		CarrerDAO model = null;
		if (!ProtoIO.LoadFromByteStream<CarrerDAO>(serverBytes, out model))
		{
			return localCarrer;
		}
		if (model == null)
		{
			return localCarrer;
		}
		if (localCarrer == null)
		{
			return model;
		}
		CarrerDAO carrerDAO = new CarrerDAO();
		carrerDAO.flag = model.flag;
		carrerDAO.name = model.name;
		if (model.stages == null)
		{
			carrerDAO.stages = localCarrer.stages;
			return carrerDAO;
		}
		if (localCarrer.stages == null)
		{
			carrerDAO.stages = model.stages;
			return carrerDAO;
		}
		carrerDAO.stages = GGResolveConflict.ResolveConflictMerge(model.stages, localCarrer.stages, new CarrerStageDAOMerger());
		return carrerDAO;
	}

	public static AchivementsDAO DefaultConflictResolution(this AchivementsDAO localAchievements, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		AchivementsDAO model = null;
		if (!ProtoIO.LoadFromByteStream<AchivementsDAO>(serverBytes, out model))
		{
			return localAchievements;
		}
		if (model == null || model.achivements == null)
		{
			GGDebug.DebugLog("Resolver: returning local achievements");
			return localAchievements;
		}
		if (localAchievements == null || localAchievements.achivements == null)
		{
			GGDebug.DebugLog("Resolver: returning remote achievements");
			return model;
		}
		AchivementsDAO achivementsDAO = new AchivementsDAO();
		achivementsDAO.achivements = new List<AchivementDAO>();
		int num = ((model.achivements.Count <= localAchievements.achivements.Count) ? localAchievements.achivements.Count : model.achivements.Count);
		for (int i = 0; i < num; i++)
		{
			if (i >= model.achivements.Count)
			{
				achivementsDAO.achivements.Add(localAchievements.achivements[i]);
				continue;
			}
			if (i >= localAchievements.achivements.Count)
			{
				achivementsDAO.achivements.Add(model.achivements[i]);
				continue;
			}
			AchivementDAO achivementDAO = new AchivementDAO();
			achivementDAO.name = model.achivements[i].name;
			achivementDAO.numStepsCompleted = GGResolveConflict.ResolveConflictTakeMax(model.achivements[i].numStepsCompleted, localAchievements.achivements[i].numStepsCompleted);
			achivementDAO.numStepsReported = GGResolveConflict.ResolveConflictTakeMax(model.achivements[i].numStepsReported, localAchievements.achivements[i].numStepsReported);
			achivementDAO.numStepsSync = GGResolveConflict.ResolveConflictTakeMax(model.achivements[i].numStepsSync, localAchievements.achivements[i].numStepsSync);
			achivementsDAO.achivements.Add(achivementDAO);
		}
		return achivementsDAO;
	}

	public static CareerDAO DefaultConflictResolution(this CareerDAO localCareer, GGCloudSyncFileIOSync sync, string fileKey)
	{
		byte[] serverBytes = sync.GetServerBytes(fileKey);
		CareerDAO model = null;
		if (!ProtoIO.LoadFromByteStream<CareerDAO>(serverBytes, out model))
		{
			return localCareer;
		}
		if (model == null || model.groups == null)
		{
			return localCareer;
		}
		if (localCareer == null || localCareer.groups == null)
		{
			return model;
		}
		CareerDAO careerDAO = new CareerDAO();
		careerDAO.groups = GGResolveConflict.ResolveConflictMerge(model.groups, localCareer.groups, new CareerGroupDAOMerger());
		return careerDAO;
	}

	public static CloudSyncData.CloudSyncFile GetFile(this CloudSyncData request, string key)
	{
		if (request == null)
		{
			return null;
		}
		foreach (CloudSyncData.CloudSyncFile file in request.files)
		{
			if (file.key == key)
			{
				return file;
			}
		}
		return null;
	}
}
